<template>
  <div class="cart-row-box">

    <el-row :gutter="20">

      <!-- 显示购物车内容区域 -->
      <el-col :span="18">
        <div class="cart-box">
          <h2 class="cart-title">
            购物车
            <el-icon>
              <font-awesome-icon :icon="['fas', 'cart-shopping']" />
            </el-icon>
          </h2>
          <el-row class="store-group-row">
            <el-col v-if="stores.length === cartItemGroups.length && cartItemGroups.length > 0"
              v-for="(item, index) in cartItemGroups" :span="24" style="margin-top: 30px;">

              <el-card v-loading="global_loading || (cart_loading && index === loading_index)" class="group-card"
                shadow="hover">
                <!-- 在购物车中的该商店商品表格 -->
                <el-table class="group-table" :data="item" @selection-change="(val) => { handleSelectChange() }"
                  :header-cell-style="headStyle" :ref="multipleTableRef[index]" :row-style="tableRowStyle">

                  <!-- 选择列 -->
                  <el-table-column type="selection" :selectable="checkSelectable">
                  </el-table-column>

                  <!-- 商品缩略图片 -->
                  <el-table-column>
                    <!-- 商店名设置在label上 -->
                    <template #header>
                      <p class="store-name">
                        <el-icon>
                          <font-awesome-icon :icon="['fas', 'store']" />
                        </el-icon>
                        {{ stores[index].storeName }}
                        <el-icon>
                          <ArrowRight />
                        </el-icon>
                      </p>
                    </template>
                    <!-- 列的内容是缩略图 -->
                    <template v-slot="scope">
                      <img v-if="scope.row.status === 0" style="filter: blur(1.5px)"
                        :src="img_url_pre(scope.row.commodity.pictures[0])" class="commodity-img" @dragstart.prevent
                        alt="商品图片" />
                      <img v-else :src="img_url_pre(scope.row.commodity.pictures[0])" class="commodity-img"
                        @dragstart.prevent alt="商品图片" />
                    </template>
                  </el-table-column>

                  <!-- 商品名 -->
                  <el-table-column prop="commodity.commodityName" align="center">
                    <template v-slot="scope">
                      <p v-if="scope.row.status === 0" style="filter: blur(1.5px)">
                        {{ scope.row.commodity.commodityName }}
                      </p>
                    </template>
                  </el-table-column>

                  <!-- 商品单价 -->
                  <el-table-column align="center">
                    <template v-slot="scope">
                      <p v-if="scope.row.status === 0" style="filter: blur(1.5px)">
                        ￥{{ scope.row.commodity.price.toFixed(2) }}
                      </p>
                      <p v-else>￥{{ scope.row.commodity.price.toFixed(2) }}</p>
                    </template>
                  </el-table-column>

                  <!-- 数量（可更改） -->
                  <el-table-column width="200">
                    <template v-slot="scope">
                      <!-- 如果商品失效，要显示失效提示 -->
                      <p v-if="scope.row.status === 0" style="display: flex; align-items: center;">
                        <el-icon style="margin-right: 5px;">
                          <CircleCloseFilled />
                        </el-icon>
                        该商品已失效
                      </p>
                      <!-- 有一个购物车项在更改物品数量时，其他的购物车项不允许更改 -->
                      <el-input-number v-else :disabled="cart_loading" v-model="scope.row.commodityNum" :min="1"
                        :max="10000000" :value-on-clear="1"
                        @change="(currentValue, oldValue) => { handleNumChange1(currentValue, oldValue); handleNumChange2(index, scope.$index) }" />
                    </template>
                  </el-table-column>

                  <!-- 删除商品 -->
                  <el-table-column width="100">
                    <template v-slot="scope">
                      <el-button type="danger" :disabled="cart_loading" @click="deleteCartItem(index, scope.$index)">
                        删除
                      </el-button>
                    </template>
                  </el-table-column>

                </el-table>
              </el-card>

            </el-col>
            <el-col v-else style="margin-top: 30px;">
              <el-card class="group-card" shadow="never" v-loading="global_loading"
                style="font-size: 30px; display: flex; justify-content: center; align-content: center; align-items: center; height: 450px;">
                <el-empty description=" ">
                  <el-icon>
                    <ShoppingCart />
                  </el-icon>
                  您的购物车是空的
                </el-empty>
              </el-card>
            </el-col>
          </el-row>
        </div>
      </el-col>

      <!-- 显示总价和买单区域 -->
      <el-col :span="6">
        <el-affix :offset="65">
          <el-card v-loading="global_loading || cart_loading">
            <p>
              <el-button type="primary" plain icon="Finished" :disabled="false" @click="selectAll">
                {{ selectedAll ? '取消' : '' }}全选
              </el-button>
              <el-button type="danger" plain icon="Delete" :disabled="totalCount === 0" @click="deleteSelected">
                删除选中
              </el-button>
            </p>
            <p style="margin-top: 20px; font-size: 18px; margin-bottom: 30px;">已选{{ totalCount }}种商品，合计：</p>
            <p style="text-align: center;">
              <span style="font-size: 18px;">￥</span>
              <span style="font-size: 36px;">{{ totalAmount.toFixed(2) }}</span>
            </p>

            <!-- 涉及的活动 -->
            <div v-if="activityList && activityList.length > 0" style="margin-top: 20px;">
              活动明细：
              <li v-for="item in activityList" style="margin-top: 5px;">
                {{ item.activityName }}：
                满
                <span style="color: #2e64c2;">{{ item.reach }}</span>
                减
                <span style="color: #2e64c2;">{{ item.reduce }}</span>
              </li>
            </div>

            <p style="margin-top: 30px; display: flex; justify-content: center;">
              <el-button :disabled="totalCount === 0" type="success" round plain icon="Wallet" style="width: 100%;"
                @click="settleSelected">
                进行结算
              </el-button>
            </p>
          </el-card>
        </el-affix>
      </el-col>

    </el-row>

  </div>
</template>

<script setup>
import { getCurrentInstance, onMounted, ref } from 'vue'
import debounce from 'lodash/debounce'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import img_url_pre from '../../utils/img_url_filter'

const router = useRouter()
const store = useStore()
const { proxy } = getCurrentInstance();

const activityList = ref([]);

const global_loading = ref(true)  // 默认开启全局loading
const cart_loading = ref(false)
const loading_index = ref(-1)

const currentValueStore = ref(-1)
const oldValueStore = ref(-1)

const totalCount = ref(0)
const totalAmount = ref(0.0)

// 注意：这几个数组需要绑定变化
const cartItemGroups = ref([])  // 二维数组，按商店分成group
const stores = ref([])
const multipleTableRef = ref([]);  // ref数组，一个元素对应一个表

const selectedAll = ref(false)

const commodityInfoList = ref([]);  // 预览订单情况用

// 设置让图片列的label，商店名，独占一整行
const headStyle = ({ row, column, rowIndex, columnIndex }) => {
  row[1].colSpan = 5
  row[2].colSpan = 0
  row[3].colSpan = 0
  row[4].colSpan = 0
  row[5].colSpan = 0
}

// 确定商品状态，如果实现不能选中（结算）
const checkSelectable = (row) => {
  return row.status === 1;
}

// 为行添加背景
const tableRowStyle = ({ row }) => {
  if (row.status === 0) {
    return {
      backgroundColor: '#C5C5C5'
    }
  }
}

// 初始化：获取购物车、获取商店名、按商店获取商品信息
const getCart = async () => {
  // 清空stores和multipleTableRef，因为getCart可能是多选删除后调用的
  stores.value = [];
  multipleTableRef.value = [];
  let res = await proxy.$api.cart.getCart(store.state.user.userId)
  // 接收购物车项
  cartItemGroups.value = res.data;
  // 遍历查询获取商店名
  for (let i = 0; i < cartItemGroups.value.length; ++i) {
    let ret = await proxy.$api.store.getStoreVo(cartItemGroups.value[i][0].storeId);
    if (ret.status === 200) {
      stores.value.push(ret.data);
    } else {
      stores.value.push({
        storeName: "该商店已关闭"
      });
    }
    multipleTableRef.value.push(ref());
  }
}

// 表格的选择发生变化时
const handleSelectChange = () => {
  cart_loading.value = true;
  // 更新汇总信息以及selectedAll
  handleSum();
}

// 暂存原本的数量，便于请求失败时，恢复为原来的数量
const handleNumChange1 = (currentValue, oldValue) => {
  currentValueStore.value = currentValue;
  oldValueStore.value = oldValue;
}

// 向后端发起改变购物车项商品数量的请求
const handleNumChange2 = (index1, index2) => {
  // 开启加载遮罩
  cart_loading.value = true;
  loading_index.value = index1;
  // 发送请求
  proxy.$api.cart.modifyCartItemNum({
    cartItemId: cartItemGroups.value[index1][index2].cartItemId,
    commodityNum: cartItemGroups.value[index1][index2].commodityNum,
  }).then(
    // 后端成功改变了商品数量
    () => {
      // 更新汇总信息
      handleSum()
      // 关闭加载遮罩
      // cart_loading.value = false;
      loading_index.value = -1;
    }
  ).catch(
    error => {
      // 关闭加载遮罩
      cart_loading.value = false;
      loading_index.value = -1;
      // 出现错误，恢复更改之前的值
      cartItemGroups.value[index1][index2].commodityNum = oldValueStore.value;
      console.log(error)
    }
  )
}

// 移除一个购物车项
const deleteCartItem = async (index1, index2) => {
  let ret;
  // 开启加载遮罩
  cart_loading.value = true;
  loading_index.value = index1;
  // 清除所有的勾选
  cancelAllSelect();
  // 发起删除购物车项请求
  try {
    ret = await proxy.$api.cart.deleteCartItem({ cartItemId: cartItemGroups.value[index1][index2].cartItemId });
  } catch (error) {
    // 关闭加载遮罩
    cart_loading.value = false;
    loading_index.value = -1;
    console.log(error);
  }

  if (ret.status === 200) {
    console.log("delete cartItem success");
    cart_loading.value = false;
    loading_index.value = -1;
    // 重新获取一下购物车
    global_loading.value = true;
    await getCart();
    global_loading.value = false;
  }
}

// 重新计算选择总数，并判断selectedAll，总价交由后端计算
const handleSum = debounce(async () => {  // 防抖500ms
  // totalAmount.value = 0.0;
  totalCount.value = 0;
  commodityInfoList.value = [];
  let cartItemValidCount = 0;  // 代表有效商品数量
  for (let i = 0; i < multipleTableRef.value.length; ++i) {
    let _tmp = multipleTableRef.value[i].value[0].getSelectionRows();
    // 累加总选择数
    totalCount.value += _tmp.length;
    // 累加总的有效商品数量
    cartItemGroups.value[i].forEach(item => cartItemValidCount += item.status);
    // 向commodityInfoList中加入选择了的商品
    _tmp.forEach(item =>
      commodityInfoList.value.push({
        storeId: cartItemGroups.value[i][0].storeId,
        commodityId: item.commodityId,
        commodityNum: item.commodityNum,
      })
    )
  }
  selectedAll.value = (totalCount.value !== 0) && (cartItemValidCount === totalCount.value);

  // 发请求到后端，计算实际总价
  let ret = await proxy.$api.order.orderPreview({
    commodityInfoList: commodityInfoList.value,
  });
  if (ret.status === 200) {
    totalAmount.value = ret.data.total;
    cart_loading.value = false;
    activityList.value = ret.data.activityList;
  }
}, 750);  // 防抖750ms

// 取消所有选择
const cancelAllSelect = () => {
  multipleTableRef.value.forEach(item => {
    item.value[0].clearSelection();
  });
  totalAmount.value = 0.0;
  totalCount.value = 0;
}

// 全选或取消全选
const selectAll = () => {
  if (selectedAll.value === false) {
    let cartItemValidCount = 0;
    // 接下来要全选
    for (let i = 0; i < multipleTableRef.value.length; ++i) {
      cartItemValidCount = 0;
      cartItemGroups.value[i].forEach((item) => {
        cartItemValidCount += item.status
      });
      if (multipleTableRef.value[i].value[0].getSelectionRows().length !== cartItemValidCount)
        multipleTableRef.value[i].value[0].toggleAllSelection();
    }
  } else {
    // 接下来要取消全选
    cancelAllSelect();
  }
  // selectedAll.value交给选择变化后触发的handleSelectChange
}

// 删除所选购物车项
const deleteSelected = async () => {
  // 开启加载遮罩
  global_loading.value = true;

  let cartItemIdList = [];
  multipleTableRef.value.forEach((item) => {
    item.value[0].getSelectionRows().forEach((subItem) => {
      cartItemIdList.push(subItem.cartItemId);
    })
  })

  await proxy.$api.cart.deleteSelectedCartItems({ cartItemIdList }).catch(error => {
    console.log(error);
    global_loading.value = false;
    ElMessage.error({ showClose: true, message: "删除选中商品失败，请稍后重试" });
  });

  // 重新获取一下购物车
  await getCart();
  totalAmount.value = 0;
  activityList.value = [];

  // 关闭加载遮罩
  global_loading.value = false;
}

/**
 * 结算购物车所选项，前往订单预览界面
 */
const settleSelected = () => {
  let selected = [];
  ElMessageBox.confirm(
    '即将前往订单预览，确定要结算选中的商品吗？',
    '确认订单',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    global_loading.value = true;

    let commodityGroup = [];
    let cartItemIdList = [];

    multipleTableRef.value.forEach((item, index) => {
      let tmp = item.value[0].getSelectionRows();
      if (tmp.length > 0) {
        commodityGroup.push([]);
        tmp.forEach((subItem) => {
          // cartItemIdList
          cartItemIdList.push(subItem.cartItemId);
          // commodityGroup
          commodityGroup.at(-1).push({
            storeVo: stores.value[index],
            commodity: subItem.commodity,
            commodityNum: subItem.commodityNum
          });
        });
      }
    });

    store.commit('order/setCommodityGroup', commodityGroup);
    store.commit('order/setCartItemIdList', cartItemIdList);

    if (store.state.order.toPreview !== true) {
      store.commit('order/reverseToPreview');
    }

    router.push('/mall/order/preview');

  }).catch(() => {
    ElMessage({ type: 'info', message: '取消结算选中购物车项' })
    global_loading.value = false;
  })
  global_loading.value = false;
}

onMounted(async () => {
  global_loading.value = true;
  await getCart().catch(error => {
    console.log(error);
    ElMessage.error({ showClose: true, message: "购物车中有来自已关闭商店的商品，请及时清理" });
  });
  global_loading.value = false;
})

</script>

<style lang="less" scoped>
.cart-row-box {
  width: 80%;
  margin: 0 auto 0 auto;

  .cart-box {
    padding-bottom: 30px;
    background-color: white;
    border-radius: 10px;
    padding-top: 20px;

    .cart-title {
      margin-left: 30px;
      /* 文字间距 */
      letter-spacing: 5px;
      font-size: 30px;
      color: rgb(0, 0, 0);
      /* 禁止选中 */
      user-select: none;
      /* 文字阴影 */
      text-shadow: 4px 4px 3px rgba(0, 0, 0, 0.1);
      display: flex;
    }

    .store-group-row {
      margin: 0 30px 0 30px;

      .group-card:hover {
        box-shadow: 0 0 14px rgba(113, 138, 187, 0.523);
        border-color: #eee;
        // transition: all 0.2s ease-in-out;
      }

      .group-card {
        border: 1px solid rgba(150, 158, 175, 0.201);
        border-radius: 8px;
        background-color: #d3dae33a;

        .group-table {
          border-radius: 3px;
          font-size: 18px;

          .store-name {
            display: flex;
            align-items: center;
            font-size: 18px;
            color: rgba(0, 0, 0, 0.719);
            margin-bottom: 5px;
            margin-top: 5px;

            .el-icon {
              margin-right: 8px;
            }
          }

          .commodity-img {
            width: 120px;
            height: 120px;
            border-radius: 5px;
          }
        }
      }
    }
  }
}
</style>